package org.jay.angla.fragment;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.achartengine.GraphicalView;
import org.jay.angla.activity.MainActivity_;
import org.jay.angla.activity.TSSettingActivity_;
import org.jay.angla.base.PhotoMeasureRecord;
import org.jay.angla.base.TimeScanningRecord;
import org.jay.angla.chart.QAChart;
import org.jay.angla.chart.TSChart;
import org.jay.angla.device.OnlabUVDevice;
import org.jay.angla.dialog.CalcRDialog;
import org.jay.angla.dialog.QANameDialog;
import org.jay.angla.dialog.QASampleDialog;
import org.jay.angla.dialog.RecordNameDialog;
import org.jay.angla.onlab.OnlabApplication;
import org.jay.angla.onlab.R;
import org.jay.angla.utils.Contants;
import org.jay.angla.utils.SharePreferenceUtil;
import org.jay.angla.utils.ToastShow;
import org.jay.angla.utils.Utils;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.AdapterView.OnItemLongClickListener;

@SuppressLint("NewApi")
public class FragmentTimeScanning extends Fragment implements
		View.OnClickListener {

	private FragmentCallbackListener mListener;
	private FrameLayout mQAChart;
	private TSChart mChart;
	private GraphicalView mChartView;

	private TextView mIntervalTextView;
	private TextView mTestModeTextView;
	private TextView mWavelengthTextView;

	private Button mStartButton;
	private Button mStopButton;
	private Button mRezeroButton;

	private ListView mListView;
	private SimpleAdapter mAdapter;
	private List<HashMap<String, String>> mData;

	private Intent mIntent;
	private int mRequestCode;
	private ToastShow mToastShow;

	private int mInterval = 2;

	private StartTestThread mStartTestThread;
	private RecordNameDialog mDialog;
	private boolean loadHistory = false;
	private int historyId;

	private boolean isTesting = false;
	private CalcRDialog mCalcRDialog;

	private TextView mRCalcTextView;

	@Override
	public void onAttach(Activity activity) {
		// TODO Auto-generated method stub
		mListener = (FragmentCallbackListener) activity;
		super.onAttach(activity);
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		View rootView = inflater.inflate(R.layout.fragment_time_scanning,
				container, false);

		mQAChart = (FrameLayout) rootView.findViewById(R.id.chart_ts);
		mChart = new TSChart(getActivity());
		mChartView = mChart.getChartView(getActivity());
		mQAChart.removeAllViews();
		mQAChart.addView(mChartView);

		mIntervalTextView = (TextView) rootView
				.findViewById(R.id.tv_time_interval);
		mTestModeTextView = (TextView) rootView.findViewById(R.id.tv_test_mode);
		mStartButton = (Button) rootView.findViewById(R.id.btn_start_test);
		mStopButton = (Button) rootView.findViewById(R.id.btn_stop_test);
		mRezeroButton = (Button) rootView.findViewById(R.id.btn_rezero_test);
		mWavelengthTextView = (TextView) rootView
				.findViewById(R.id.tv_wavelength);
		mRCalcTextView = (TextView) rootView.findViewById(R.id.tv_rcalc);
		mRCalcTextView.setTextColor(Color.GREEN);

		mStartButton.setOnClickListener(this);
		mStopButton.setOnClickListener(this);
		mRezeroButton.setOnClickListener(this);
		mRCalcTextView.setOnClickListener(this);

		// init for listview
		mListView = (ListView) rootView.findViewById(R.id.lv_ws);
		mData = new ArrayList<HashMap<String, String>>();
		mAdapter = new SimpleAdapter(getActivity(), mData,
				R.layout.item_ts_test, new String[] { "id", "abs", "trans",
						"energy" }, new int[] { R.id.item_number,
						R.id.item_abs, R.id.item_trans, R.id.item_energy });
		mListView.setAdapter(mAdapter);

		mDialog = new RecordNameDialog(getActivity());
		mDialog.setOnClickListener(this);

		mCalcRDialog = new CalcRDialog(getActivity());
		mCalcRDialog.setOnClickListener(this);

		loadSp();
		if (loadHistory) {
			List<String> namesList = OnlabApplication.getInstance()
					.getTimeScanningDB().getTables();
			// load select record
			String recordname = namesList.get(historyId);
			List<TimeScanningRecord> list = OnlabApplication.getInstance()
					.getTimeScanningDB().getRecords(recordname);
			clearData();
			for (int i = 0; i < list.size(); i++) {
				TimeScanningRecord record = list.get(i);
				addOneTestItem(record);
				float yValue = 0.00f;
				if (OnlabApplication.getInstance().getSpUtil().getTestMode() == TSSettingActivity_.TEST_MODE_ABS) {
					yValue = record.getAbs();
				} else {
					yValue = record.getTrans();
				}
				mChart.add(record.getSecond(), yValue);
			}
			mChartView.postInvalidate();
		}

		mStartTestThread = new StartTestThread();
		mIntent = new Intent();
		mIntent.setClass(getActivity(), TSSettingActivity_.class);
		mToastShow = new ToastShow(getActivity());
		if (!loadHistory) {
			mRequestCode = 0;
			startActivityForResult(mIntent, mRequestCode);
		}
		isTesting = false;
		// mCalcRButton.setEnabled(false);
		mRCalcTextView.setClickable(false);
		return rootView;
	}

	@Override
	public void onDestroyView() {
		// TODO Auto-generated method stub
		super.onDestroyView();
		mStartTestThread.setStop();
		((MainActivity_) getActivity()).setMainButtonsEnable();
		loadHistory = false;
	}

	public void loadHistoryById(int id) {
		loadHistory = true;
		historyId = id;
		if (isAdded()) {
			List<String> namesList = OnlabApplication.getInstance()
					.getTimeScanningDB().getTables();
			// load select record
			String recordname = namesList.get(historyId);
			List<TimeScanningRecord> list = OnlabApplication.getInstance()
					.getTimeScanningDB().getRecords(recordname);
			clearData();
			for (int i = 0; i < list.size(); i++) {
				TimeScanningRecord record = list.get(i);
				addOneTestItem(record);
				float yValue = 0.00f;
				if (OnlabApplication.getInstance().getSpUtil().getTestMode() == TSSettingActivity_.TEST_MODE_ABS) {
					yValue = record.getAbs();
				} else {
					yValue = record.getTrans();
				}
				mChart.add(record.getSecond(), yValue);
			}
			mChartView.postInvalidate();
		}
	}

	private void clearData() {
		mData.clear();
		mAdapter.notifyDataSetChanged();
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		// super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == 99) {
			float wavelength = data.getFloatExtra("wavelength", 546.0f);
			float uplimit = data.getFloatExtra("uplimit", 3.00f);
			float downlimit = data.getFloatExtra("downlimit", 0.00f);
			int startTime = data.getIntExtra("starttime", 0);
			int endTime = data.getIntExtra("endtime", 1000);
			int testMode = data.getIntExtra("testmode",
					TSSettingActivity_.TEST_MODE_ABS);
			float interval = data.getFloatExtra("interval", 1);

			prepareForUI(wavelength, interval, uplimit, downlimit, startTime,
					endTime, testMode);
			mChart.clear();
			for (int i = 0; i < mData.size(); i++) {
				HashMap<String, String> item = mData.get(i);
				float yValue = 0.00f;
				if (testMode == TSSettingActivity_.TEST_MODE_ABS) {
					yValue = Float.parseFloat(item.get("abs"));
				} else {
					yValue = Float.parseFloat(item.get("trans"));
				}
				mChart.add(Integer.parseInt(item.get("second")), yValue);
				Log.d(Contants.TAG, "yval = " + yValue);
			}
			mChartView.postInvalidate();
			((MainActivity_) getActivity()).setWL(wavelength);
			((MainActivity_) getActivity()).showWavelengthReset();
		} else {
			loadSp();
		}
	}

	private void loadSp() {
		SharePreferenceUtil sp = OnlabApplication.getInstance().getSpUtil();
		float wavelength = sp.getWavelength();
		float uplimit = sp.getUpLimit();
		float downlimit = sp.getDownLimit();
		int startTime = sp.getStartTime();
		int endTime = sp.getEndTime();
		int testMode = sp.getTestMode();
		float interval = sp.getInterval();

		prepareForUI(wavelength, interval, uplimit, downlimit, startTime,
				endTime, testMode);
	}

	private void prepareForUI(float wavelength, float interval, float uplimit,
			float downlimit, int startTime, int endTime, int testMode) {
		mIntervalTextView.setText(getString(R.string.interval_string)
				+ interval + getString(R.string.second));
		mInterval = (int) interval;
		String testModeString = getString(R.string.mode_string);
		if (testMode == TSSettingActivity_.TEST_MODE_ABS) {
			testModeString += getString(R.string.abs_string);
			mChart.setAbsTitle();
			if (mData.size() > 0) {
				mChart.clear();
				for (int i = 0; i < mData.size(); i++) {
					mChart.add(Float.parseFloat(mData.get(i).get("second")),
							Float.parseFloat(mData.get(i).get("abs")));
				}
			}
		} else {
			testModeString += getString(R.string.trans_string);
			mChart.setTransTitle();
			if (mData.size() > 0) {
				mChart.clear();
				for (int i = 0; i < mData.size(); i++) {
					mChart.add(Float.parseFloat(mData.get(i).get("second")),
							Float.parseFloat(mData.get(i).get("trans")));
				}
			}
		}
		mTestModeTextView.setText(testModeString);
		// config chart
		// mToastShow.toastShow("endTime = " + endTime);
		mChart.setXLimit(startTime, endTime);
		mChart.setYLimit(downlimit, uplimit);
		mChartView.postInvalidate();

		mWavelengthTextView.setText(getString(R.string.test_wavelength)
				+ wavelength + " nm");
		// ((MainActivity_) getActivity()).setWL(wavelength);
	}

	private void addOneTestItem(TimeScanningRecord record) {
		HashMap<String, String> item = new HashMap<String, String>();
		item.put("id", "" + (mData.size() + 1));
		item.put("second", "" + record.getSecond());

		if (OnlabApplication.getInstance().getSpUtil().isLowAccuracy()) {
			item.put("abs", String.format("%.3f", record.getAbs()));
			item.put("trans", String.format("%.1f", record.getTrans()));

		} else {
			item.put("abs", String.format("%.4f", record.getAbs()));
			item.put("trans", String.format("%.2f", record.getTrans()));
		}

		item.put("energy", "" + record.getEnergy());
		item.put("date", "" + record.getDate());
		mData.add(item);
		mAdapter.notifyDataSetChanged();
		if (mData.size() > 0) {
			mListView.setSelection(mData.size() - 1);
		}
	}

	private void clearListItem() {
		mData.clear();
		mAdapter.notifyDataSetChanged();
	}

	private Handler mTestHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			int what = msg.what;
			Bundle bundle = msg.getData();
			if (what == 99) {
				float abs = bundle.getFloat("ABS");
				float trans = bundle.getFloat("TRANS");
				int energy = bundle.getInt("ENERGY");
				int time = msg.arg1;
				if (OnlabApplication.getInstance().getSpUtil().getTestMode() == TSSettingActivity_.TEST_MODE_ABS) {
					mChart.add(time, abs);
				} else {
					mChart.add(time, trans * 100);
				}
				mChartView.postInvalidate();
				if (time != 0) {
					addOneTestItem(new TimeScanningRecord(-1, time, abs,
							trans * 100, energy, System.currentTimeMillis()));
				}

			} else if (what == 97) {
				mToastShow.toastShow(getString(R.string.test_end));
				mStartButton.setEnabled(true);
				// mCalcRButton.setEnabled(true);
				mRCalcTextView.setClickable(true);
				float end = 0.0f;
				float start = 0.0f;
				if (OnlabApplication.getInstance().getSpUtil().getTestMode() == TSSettingActivity_.TEST_MODE_ABS) {
					start = Float.parseFloat(mData.get(0).get("abs"));
					end = Float.parseFloat(mData.get(mData.size() - 1).get(
							"abs"));

				} else {
					start = Float.parseFloat(mData.get(0).get("trans"));
					end = Float.parseFloat(mData.get(mData.size() - 1).get(
							"trans"));
				}
				SharePreferenceUtil sp = OnlabApplication.getInstance()
						.getSpUtil();
				float rate = (end - start)
						/ (sp.getEndTime() - sp.getStartTime());
				mRCalcTextView.setText(String.format("斜率: %.4f", rate));
			} else if (what == 98) {
				mChart.clear();
				mChartView.postInvalidate();
				clearListItem();
			}
		};
	};

	private class StartTestThread implements Runnable {

		private boolean isStart = false;
		private int interval;
		private int index = 0;

		public boolean isRunning() {
			return isStart;
		}

		public void setStart() {
			isStart = true;
		}

		public void setStop() {
			isStart = false;
		}

		public void setInterval(int val) {
			interval = val;
		}

		@Override
		public void run() {
			// TODO Auto-generated method stub
			index = 0;

			try {
				Thread.sleep(interval * 1000);
				// send start
				Message msg0 = mTestHandler.obtainMessage();
				msg0.what = 98;
				msg0.sendToTarget();
				// send first frame
				float abs = ((MainActivity_) getActivity()).getAbs();
				float trans = ((MainActivity_) getActivity()).getTrans();
				int energy = ((MainActivity_) getActivity()).getEnergy();
				Message msg = mTestHandler.obtainMessage();
				Bundle bundle = new Bundle();
				bundle.putFloat("ABS", abs);
				bundle.putFloat("TRANS", trans);
				bundle.putInt("ENERGY", energy);
				msg.arg1 = index;
				msg.setData(bundle);
				msg.what = 99;
				msg.sendToTarget();

				while (isStart) {
					int endTime = OnlabApplication.getInstance().getSpUtil()
							.getEndTime();
					index = index + interval;
					if (index > endTime) {
						// send stop
						Message msg1 = mTestHandler.obtainMessage();
						msg1.what = 97;
						msg1.sendToTarget();
						break;
					}
					abs = ((MainActivity_) getActivity()).getAbs();
					trans = ((MainActivity_) getActivity()).getTrans();
					energy = ((MainActivity_) getActivity()).getEnergy();
					msg = mTestHandler.obtainMessage();
					bundle = new Bundle();
					bundle.putFloat("ABS", abs);
					bundle.putFloat("TRANS", trans);
					bundle.putInt("ENERGY", energy);
					msg.arg1 = index;
					msg.setData(bundle);
					msg.what = 99;
					msg.sendToTarget();
					// wait some interval time
					Thread.sleep(interval * 1000);
				}
				isStart = false;
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	public void setting() {
		mIntent.setClass(getActivity(), TSSettingActivity_.class);
		mToastShow = new ToastShow(getActivity());
		mRequestCode = 0;
		startActivityForResult(mIntent, mRequestCode);
	}

	public void save() {
		String name = getString(R.string.time_scanning_exp_string);
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
		name += format.format(new Date());
		mDialog.show();
		mDialog.setEditText(name);
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {

		case R.id.btn_start_test:
			if (!mStartTestThread.isRunning()) {
				mStartTestThread.setInterval(mInterval);
				mStartTestThread.setStart();
				new Thread(mStartTestThread).start();
				mStartButton.setEnabled(false);
			} else {
				mToastShow.toastShow("正在测试中");
			}
			break;
		case R.id.btn_stop_test:
			mStartTestThread.setStop();
			mStartButton.setEnabled(true);
			break;
		case R.id.btn_rezero_test:
			((MainActivity_) getActivity()).rezero();
			break;

		case R.id.dialog_save_button:
			String name = mDialog.getEditText();
			if (name.length() < 1) {
				mToastShow.toastShow(getString(R.string.name_cannot_null));
			} else {
				// check the name is already availiable
				List<String> namesList = OnlabApplication.getInstance()
						.getTimeScanningDB().getTables();
				for (int i = 0; i < namesList.size(); i++) {
					if (namesList.get(i).equals(name)) {
						mToastShow
								.toastShow(getString(R.string.name_already_exist));
						return;
					}
				}

				String recordName = name;
				for (int i = 0; i < mData.size(); i++) {
					int index = 0;
					int second = 0;
					float abs = 0.0f;
					float trans = 0.0f;
					int energy = 0;
					long date = 0;

					HashMap<String, String> map = mData.get(i);
					index = Integer.parseInt(map.get("id"));
					second = Integer.parseInt(map.get("second"));
					abs = Float.parseFloat(map.get("abs"));
					trans = Float.parseFloat(map.get("trans"));
					energy = Integer.parseInt(map.get("energy"));
					date = Long.parseLong(map.get("date"));

					Log.d(Contants.TAG, "index = " + index + ", second = "
							+ second + ", abs = " + abs);
					TimeScanningRecord record = new TimeScanningRecord(index,
							second, abs, trans, energy, date);
					OnlabApplication.getInstance().getTimeScanningDB()
							.saveRecord(recordName, record);
				}
				mDialog.dismiss();
			}
			break;
		case R.id.dialog_cancel_button:
			mDialog.dismiss();
			break;
		case R.id.tv_rcalc:
			mCalcRDialog.show();
			break;
		case R.id.dialog_calc_button:
			float startTime = mCalcRDialog.getStartTime();
			float startVal = 0.0f;
			float endTime = mCalcRDialog.getEndTime();
			float endVal = 0.0f;

			if (startTime < 0 || (endTime < 0)) {
				mToastShow.toastShow("请输入正确的时间点");
			} else {
				for (int i = 0; i < mData.size(); i++) {
					float time = Float.parseFloat(mData.get(i).get("second"));
					if (time >= startTime) {
						if (OnlabApplication.getInstance().getSpUtil()
								.getTestMode() == TSSettingActivity_.TEST_MODE_ABS) {
							startVal = Float
									.parseFloat(mData.get(i).get("abs"));
						} else {
							startVal = Float.parseFloat(mData.get(i).get(
									"trans"));
						}
						break;
					}
				}
				for (int i = 0; i < mData.size(); i++) {
					float time = Float.parseFloat(mData.get(i).get("second"));
					if (time >= endTime) {
						if (OnlabApplication.getInstance().getSpUtil()
								.getTestMode() == TSSettingActivity_.TEST_MODE_ABS) {
							endVal = Float.parseFloat(mData.get(i).get("abs"));
						} else {
							endVal = Float
									.parseFloat(mData.get(i).get("trans"));
						}
						break;
					}
				}

				float r = (endVal - startVal) / (endTime - startTime);
				mRCalcTextView.setText(String.format("斜率: %.4f", r));
				// mToastShow.toastShow(String.format(
				// "start = %f, %f, end = %f, %f, r = %f", startTime,
				// startVal, endTime, endVal, r));
				mCalcRDialog.dismiss();
			}
			break;
		case R.id.dialog_return_button:
			mCalcRDialog.dismiss();
			break;
		default:
			break;
		}

	}
}
